package com.tvunetworks.center.device.controller.feign;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.github.pagehelper.PageInfo;
import com.tvunetworks.center.common.feign.DeviceFeignInterface;
import com.tvunetworks.center.common.model.*;
import com.tvunetworks.center.common.model.dto.MsgpipeDTO;
import com.tvunetworks.center.common.model.param.OverlayParam;
import com.tvunetworks.center.common.model.param.ReceiverDeleteExtParam;
import com.tvunetworks.center.common.model.param.SetOverlayParam;
import com.tvunetworks.center.common.model.ps.PSR;
import com.tvunetworks.center.common.model.ps.PST;
import com.tvunetworks.center.common.model.vo.TimeLockDeviceMsgVo;
import com.tvunetworks.center.common.util.JsonUtil;
import com.tvunetworks.center.common.util.MyUtil;
import com.tvunetworks.center.common.util.Result;
import com.tvunetworks.center.common.util.ResultUtil;
import com.tvunetworks.center.device.constant.CommandConstant;
import com.tvunetworks.center.device.model.MyDevice;
import com.tvunetworks.center.device.model.OveryLayParam;
import com.tvunetworks.center.device.model.PtsPrs;
import com.tvunetworks.center.device.model.vo.TimeLockMsgResult;
import com.tvunetworks.center.device.service.*;
import com.tvunetworks.center.device.service.feign.UserFeignService;
import com.tvunetworks.center.device.service.impl.DevicePairService;
import com.tvunetworks.center.gs.model.Device;
import com.tvunetworks.center.gs.model.SfUser;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import net.spy.memcached.MemcachedClient;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.*;

/**
 * @program: tvucc-device
 * @description: DeviceFeignController
 * @author lebronchen
 * @create: 2019-03-14 20:15
 **/
@RestController
@RequestMapping("/feign")
@Slf4j
public class DeviceFeignController implements DeviceFeignInterface {

    @Autowired
    private DeviceService deviceService;
    @Autowired
    private UserDeviceService userDeviceService;
    @Autowired
    private DevicePairService devicePairService;
    @Autowired
    private ExtService extService;
    @Autowired
    private ReceiverControlService receiverControlService;
    @Autowired
    private UserFeignService userFeignService;
    @Autowired
    private ExternalReceiverRelationService externalReceiverRelationService;

    @Autowired
    private TokenService tokenService;
    @Autowired
    private UserBehaviorService userBehaviorService;
    @Autowired
    private TimeLockEventService timeLockEventService;
    @Autowired
    private CustomizedLiveService customizedLiveService;
    @Autowired
    @Qualifier("psMemcacheClient")
    private MemcachedClient psMemcacheClient;
    @Value("${tpdsMemcacheUserKey}")
    private String tpdsMemcacheUserKey;
    @Autowired
    @Qualifier("ccMemcacheClient")
    private MemcachedClient ccMemcacheClient;
    @Autowired
    private RouterService routerService;
    @Autowired
    private UserDeviceRecordService userDeviceRecordService;

    @Override
    public Device getMemDevice(String peerId) {
        if (StringUtils.isBlank(peerId)) {
            return null;
        }
        return deviceService.getMemDevice(peerId);
    }

    @Override
    public Device getDBDevice(String peerId) {
        return deviceService.getDevice4DB(peerId);
    }

    @Override
    public List<Device> listMemDevice(@RequestBody ListDeviceParam param) {
        String peerIds = param.getPeerIds();
        if (StringUtils.isBlank(peerIds)) {
            return null;
        }
        return deviceService.listMemDevice(Arrays.asList(peerIds.split(",")));
    }

    @Override
    public Map<String, Device> mapMemDevice(@RequestBody ListDeviceParam param) {
        List<Device> devices = this.listMemDevice(param);
        if (devices == null) {
            return null;
        }
        Map<String, Device> resultMap = new HashMap<>();

        for (Device device : devices) {
            resultMap.put(device.getPeerId(), device);
        }
        return resultMap;
    }

    @Override
    public Device getCurrentDevice(@RequestParam("peerId") String peerId) {
        return deviceService.getCurrentDevice(peerId);
    }



    @Override
    public boolean doubleCheckDeviceOffline(@RequestParam("peerId") String peerId) {
        return deviceService.doubleCheckDeviceOffline(peerId);
    }

    @Override
    public boolean isLive(@RequestParam(value = "peerId") String peerId) {
        return deviceService.isLive(peerId);
    }

    @Override
    public Map<String,String> listDeviceMetadata(@RequestParam(value = "peerIdList") Collection<String> peerIdList) {
        return deviceService.listDeviceMetadata(peerIdList);
    }

    @Override
    public List<Device> listCurrentDevice(@RequestBody ListDeviceParam param) {
        String peerIds = param.getPeerIds();
        if (StringUtils.isBlank(peerIds)) {
            return null;
        }
        return deviceService.listCurrentDevice(Arrays.asList(peerIds.split(",")));
    }

    @Override
    public Map<String, Device> mapCurrentDevice(@RequestBody ListDeviceParam param) {
        List<Device> devices = this.listCurrentDevice(param);
        if (devices == null) {
            return null;
        }
        Map<String, Device> resultMap = new HashMap<>();
        for (Device device : devices) {
            resultMap.put(device.getPeerId(), device);
        }
        return resultMap;
    }
    @Override
    public List<String> listRPairT(String rid) {
        return devicePairService.listRPairT(rid);
    }

    @Override
    public List<String> listRPairX(String rid) {
        try {
            return devicePairService.listCacheRPairX(rid);
        } catch (Exception e) {
            log.error(e.toString(), e);
        }
        return null;
    }

    @Override
    public List<String> listTPairR(String tid) {
        return devicePairService.listTPairR(tid);
    }

    @Override
    public List<String> listXPairR(String xid) {
        try {
            return devicePairService.listCacheXPairR(xid);
        } catch (IOException e) {
            log.error(e.toString(), e);
        }
        return null;
    }

    @Override
    public Result<String> addExt(@RequestBody Device device) {
        if (device == null || StringUtils.isBlank(device.getName()) || StringUtils.isBlank(device.getUrl()) || StringUtils.isBlank(device.getType())) {
            return ResultUtil.paramError();
        }
        return extService.addExt(device);
    }

    @Override
    public Result<String> updateExt(@RequestBody Device device) {
        if (device == null || StringUtils.isBlank(device.getName()) || StringUtils.isBlank(device.getUrl()) || StringUtils.isBlank(device.getPeerId())) {
            return ResultUtil.paramError();
        }
        return extService.updateExt(device);
    }

    @Override
    public Result<String> updateDeviceMetadata(@RequestBody Device device) {
        if (device == null || device.getMetaData() == null || StringUtils.isBlank(device.getPeerId())){
            return ResultUtil.paramError();
        }
        String peerId = device.getPeerId();
        MyDevice dbDevice = deviceService.getDBDevice(peerId);
        dbDevice.setMetaData(device.getMetaData());
        deviceService.updateDevice(dbDevice);
        return ResultUtil.success();
    }

    @Override
    public Result<String> deleteExt(@RequestParam String peerId) {
        return extService.deleteExt(peerId);
    }
    @Override
    public void deleteRExt(@RequestParam String rid,@RequestParam String sourceId) {
         extService.deleteRExt(rid,sourceId);
    }

    @Override
    public Set<String> listRsPairTids(@RequestBody Set<String> rids) {
        if (CollectionUtils.isEmpty(rids)) {
            return new HashSet<>();
        }
        return devicePairService.listRsPairTids(rids);
    }

    @Override
    public void receiverDeleteExt(@RequestBody ReceiverDeleteExtParam param) {
        externalReceiverRelationService.receiverDeleteExt(param);
    }

    @Override
    public Result<String> deleteGrid(@RequestParam String peerId) {
        return extService.deleteGrid(peerId);
    }

    @Override
    public Result<String> addExtToReceiver(@RequestParam(value = "rid") String rid, @RequestParam(value = "extPeerId") String extPeerId) {
        return extService.addExtToReceiver(rid, extPeerId);
    }

    @Override
    public Result<String> addEventExtToReceiver(String rid, String extPeerId,String type) {
        log.error("2.start send to R tid="+extPeerId+",and rid="+rid);
        return extService.addEventExtToReceiver(rid, extPeerId,type);
    }

    @Override
    public List<String> listExtBindedRids(@RequestParam String peerId) {
        return extService.listExtBindedRids(peerId);
    }

    @Override
    public void correlateExtPairedR(@RequestParam String peerId, @RequestParam String addRids, @RequestParam String removeRids) {
        extService.correlateExtPairedR(peerId, addRids, removeRids);
    }



    /**
     * mysource page Details info
     * @param sourceId sourceId
     * @throws IOException 编译异常
     * @return String
     *
     */

    public String queryDetailinfo(@RequestParam(value = "sourceId") String sourceId) throws IOException {
        return deviceService.queryDetail(sourceId);
    }

    /**
     *
     * @param sourceId sourceId
     * @return String
     * @throws IOException 编译异常
     */
    public String queryBatteryById(@RequestParam(value = "sourceId") String sourceId) throws IOException {
        return deviceService.queryBatteryById(sourceId);
    }

    @Override
    public List<String> listTTokenPairR(String tId) throws IOException {
        return tokenService.listTTokenPairR(tId);
    }

    @Override
    public String queryReceiver(@RequestBody UserBehavior userBehavior, @RequestParam("userId") String userId) {
        String resulet = null;
        try {
            resulet = JsonUtil.toJsonStr(userDeviceService.queryReceiver(userBehavior,userId));
        } catch (IOException e) {
            log.error("msg:{},e:{}",e.getMessage(),e);
        }
        return resulet;
    }

    @Override
    public Map<String, String> getUserBehavior(@RequestParam("userId") String userId, @RequestParam("pn") String pn) {
        return userBehaviorService.getUserBehavior(userId, pn);
    }

    @Override
    public List checkDevieTimeLockStatus(String userId, String peerIds) {
        List<String> peerIdList = Arrays.asList(peerIds.split(","));
        List<TimeLockMsgResult> list = timeLockEventService.checkDevieTimeLockStatus(userId, peerIdList);
        return list;
    }

    @Override
    public void updateUserBehavior(UserBehavior userBehavior) {
        try {
            userBehaviorService.updataUserBehavior(userBehavior);
        } catch (Exception e) {
            log.error("====== updateUserBehavior exception ======",e);
        }
    }
    @Override
    public void updateUserBehaviorForMv(@RequestBody UserBehavior userBehavior) {
        try {
            userBehaviorService.updataUserBehaviorForMv(userBehavior);
        } catch (Exception e) {
            log.error("====== updateUserBehavior exception ======",e);
        }
    }

    @Override
    public List<String> getBindTRPeerIdList(String userId) {
        return userDeviceService.getBindTRPeerIdList(userId);
    }

    @Override
    public List<UserBehavior> queryUserBehaviorByExample(@RequestBody UserBehavior userBehavior) {
        return userBehaviorService.queryUserBehaviorByExample(userBehavior);
    }
    @Override
    public int delUserBehavior(@RequestBody UserBehavior userBehavior) {
        return userBehaviorService.delUserBehavior(userBehavior);
    }

    @Override
    public Result<String> isDeviceExist(@RequestParam String oldPeerId, @RequestParam String newPeerId) {
        return deviceService.isDeviceExist(oldPeerId, newPeerId);
    }

    @Override
    public Result<String> checkCopy(@RequestParam String oldPeerId, @RequestParam String newPeerId, @RequestParam String taskId) {
        return deviceService.checkCopy(oldPeerId, newPeerId, taskId);
    }

    @Override
    public Result<String> copyDevice(@RequestParam String oldPeerId, @RequestParam String newPeerId, @RequestParam String taskId) {
        return deviceService.copyDevice(oldPeerId, newPeerId, taskId);
    }

    @Override
    public Result<String> deleteDevice(@RequestParam String peerId, @RequestParam String taskId) {
        return deviceService.deleteDevice(peerId, taskId);
    }

    @Override
    public Map<String, Object> getPSR() {
        Map<String, PSR> psr = PtsPrs.getPrs();
        if (CollectionUtils.isEmpty(psr)) {
            return null;
        }
        Map<String, Object> map = new HashMap<>(psr.size());
        psr.forEach((key, value) -> map.put(key, value));
        return map;
    }

    @Override
    public Map<String, Object> getPST() {
        Map<String, PST> pst = PtsPrs.getPts();
        if (CollectionUtils.isEmpty(pst)) {
            return null;
        }
        Map<String, Object> map = new HashMap<>(pst.size());
        pst.forEach((key, value) -> map.put(key, value));
        return map;
    }

    @Override
    public void preloadExtXToR(@RequestParam("rid") String rid) {
        deviceService.preloadExtXToR(rid);
    }

    @Override
    public Result<String> startLive(@RequestParam("rid") String rid, @RequestParam("sourceId") String sourceId) {
        return receiverControlService.startLiveForAPI(rid, sourceId);
    }

    @Override
    public Result<String> stopLive(@RequestParam("rid") String rid, @RequestParam(name = "sourceId", required = false) String sourceId) {
        return receiverControlService.stopLiveForAPI(rid, sourceId);
    }


    //    @Override
//    public List<Device> listFile(String userId,String name, int pageNum, int pageSize) {
//        return deviceService.listFile(userId,name,pageNum,pageSize);
//    }
//
//    @Override
//    public int listFileCount(String userId, String name) {
//        return deviceService.listFileCount(userId,name);
//    }
    @Override
    public Result<String> listDeviceLocationByMultiIpOrPeerIds(@RequestParam("peerIps") String peerIps,@RequestParam("peerIds") String peerIds,@RequestParam("mapType") String mapType){
        return deviceService.listDeviceLocationByMultiIpOrPeerId(peerIps,peerIds,mapType);
    }
    @Override
    public Result<String> listGPSByMultiPeerId(@RequestParam("peerIds")String peerIds){
        return deviceService.listGPSByMultiPeerId(peerIds);
    }

    @Override
    public void setToTpdsMemcache(@RequestParam("key")String key, @RequestParam("value") String value) {
        deviceService.setToTpdsMemcache(key,value);
    }

    @Override
    public void processTimeLockMessage(@RequestBody MsgpipeDTO message) {
        timeLockEventService.processTimeLockMessage(message);
    }

/*    @Override
    public List<TimeLockVo> listTimeLockDeviceByUserId(@RequestParam("userId") String userId) {
       return timeLockEventService.listTimeLockDeviceByUserId(userId);
    }*/

    @Override
    public Result<String> getMetadataList(@RequestParam("peerIds") String peerIds) {
        try {
            Result<String>  result =  deviceService.getMetadataList(peerIds);
            return result;
        } catch (Exception e) {
            log.error("msg:{},e:{}",e.getMessage(),e);
        }
        return null;
    }

    @Override
    public Map<String, SfUser> getUserInfoMap() {
        return (Map<String, SfUser>) psMemcacheClient.get(tpdsMemcacheUserKey);
    }

    @Override
    public void sendMsgPipeToQuerySlotStatus(@RequestParam("peerId") String peerId) throws Exception {
        routerService.sendMsgPipeToQuerySlotStatus(peerId);
    }

    @Override
    public String findSlotsMsg(@RequestParam("type")String type,@RequestParam("module") String module,@RequestParam("tid")String tid) throws Exception {
        return routerService.findSlotsMsg(type,module,tid);
    }

    @Override
    public String findPeerMsg(@RequestParam("type")String type,@RequestParam("module") String module,@RequestParam("tid")String tid,@RequestParam("userid")String userid) throws Exception {
        return routerService.findPeerMsg(type,module,tid,userid);
    }

    @Override
    public void processRouterType(String msg) {
        routerService.saveSlotsStatusToRedis(msg);
    }

    @Override
    public String routerStatus(String type, String module, String tid, String userid) throws Exception {
        return routerService.routerStatus(type,module,tid,userid);
    }

    @Override
    public void saveToMemcach(@RequestParam("key")String key,@RequestParam("value") String value,@RequestParam("time") int time) {
        ccMemcacheClient.set(key,time,value);
    }

    @Override
    public Object getFromMemcach(@RequestParam("key")String key) {
        return ccMemcacheClient.get(key);
    }

    @Override
    public List<Device> listDeviceByExample(@RequestBody Device device) {
        return deviceService.listDeviceByExample(device);
    }

    @Override
    public Result<String> getRSourceTypeList(String rid) {
        Map modelMap = new HashMap();
        modelMap.put("ClientRequestId",UUID.randomUUID());
        try {
            String params = MyUtil.MAPPER.writeValueAsString(modelMap);
            return receiverControlService.command(rid, CommandConstant.WEBR_SOURCE_TYPE,params);
        } catch (JsonProcessingException e) {
            log.error("msg:{},e:{}",e.getMessage(),e);
        }
       return ResultUtil.paramError();
    }

    @Override
    public PageInfo<ExtendExternal> getGLinkList(@RequestBody SearchDeviceParam searchDeviceParam) {
        return deviceService.getGLinkList(searchDeviceParam);
    }

    @Override
    public Result<String> getRTILList(String rid) {
        Map modelMap = new HashMap();
        modelMap.put("Name","AgoraPeerManager");
        try {
            String params = MyUtil.MAPPER.writeValueAsString(modelMap);
             Result<String> rTIL = receiverControlService.command(rid, CommandConstant.GET_SOURCE_TYPE,params);
             return  rTIL;
        } catch (JsonProcessingException e) {
            log.error("msg:{},e:{}",e.getMessage(),e);
        }

        return ResultUtil.error("get AgoraPeerManager error");
    }

    @Override
    public void saveUserDeviceRecord(@RequestBody UserDeviceRecord userDeviceRecord) {
        userDeviceRecordService.saveRecord(userDeviceRecord);
    }

    @Override
    public void saveUserDeviceRecords(@RequestBody List<UserDeviceRecord> userDeviceRecords) {
        if (CollectionUtils.isEmpty(userDeviceRecords)) {
            return;
        }
        for (UserDeviceRecord userDeviceRecord : userDeviceRecords) {
            userDeviceRecordService.saveRecord(userDeviceRecord);
        }
    }

    @Override
    public String getReceiverPSBuild(@RequestParam("peerId") String peerId) {
        PSR psr = PtsPrs.getPrs().get(peerId.toLowerCase());
        if (psr == null) {
            return null;
        }
        return psr.getBuild();
    }

    /**
     *  更新Extenal
     * @param peerId peerId
     * @param url url
     * @throws Exception 编译异常
     */
    public void updateExtenal(@RequestParam("peerId") String peerId,@RequestParam("url") String url) throws Exception{
        ExtendExternal extendExternal = new ExtendExternal();
        extendExternal.setPeerId(peerId);
        extendExternal.setUrl(url);
        receiverControlService.updateExtentEernal(extendExternal);
    }

    @Override
    public  Map<String,List<Device>> listReceiversGrid(@RequestBody List<String> rids) {
       return deviceService.listReceiversGrid(rids);
    }

    @Override
    public List<Device> getLocalSDIFromWebR(@RequestParam("rid") String rid) {
        return deviceService.getLocalSDIFromWebR(rid);
    }

    @Override
    public List<Device> getExtFromWebR(@RequestParam("rid") String rid) {
        return deviceService.getExtFromWebR(rid);
    }

    @Override
    public List<TimeLockDeviceMsgVo> listOpenTimeLockReceiverByRids(@RequestBody List<String> rids) {
        return timeLockEventService.listOpenTimeLockReceiverByRids(rids);

    }

    @Override
    public List<TimeLockDeviceMsgVo> getAllReceiverTimeLockMsg() {
        return timeLockEventService.getAllReceiverTimeLockMsg();

    }


    /*@Override
    public List<TimeLockDeviceMsgVo> listOpenTimeLockPackByRids(@RequestParam("rids") List<String> rids) {
        return timeLockEventService.listOpenTimeLockPackByRids(rids);

    }

    @Override
    public List<TimeLockDeviceMsgVo> listOpenTimeLockPackByUserId(String userId) {
        return timeLockEventService.listOpenTimeLockPackByUserId(userId);
    }*/



    @SneakyThrows
    @Override
    public Result<String> setOverlay(@RequestBody com.tvunetworks.center.common.model.param.OverlayParam params) {
        String receiverId = params.getReceiverId();
        List<SetOverlayParam> setOverlayParams = params.getSetOverlayParams();
        OveryLayParam param = new OveryLayParam();
        param.setOverlayList(setOverlayParams);
        param.setVersion("1.0.0");
        String s = JsonUtil.toJsonStr(param);
        Result<String> rTIL = receiverControlService.command(receiverId, CommandConstant.SET_OVERLAY,s);
        return  rTIL;
    }


    @Override
    public Result<String> startOverlay(@RequestBody OverlayParam params) {
        String receiverId = params.getReceiverId();
        Result<String> rTIL = receiverControlService.command(receiverId, CommandConstant.START_OVERLAY);
        return rTIL;
    }

    @Override
    public Result<String> stopOverlay(@RequestBody OverlayParam params) {
        String receiverId = params.getReceiverId();
        Result<String> rTIL = receiverControlService.command(receiverId, CommandConstant.STOP_OVERLAY);
        return rTIL;

    }
}
